package com.crazy.common.page;

import static java.lang.String.format;
import static org.springframework.web.util.WebUtils.FORWARD_SERVLET_PATH_ATTRIBUTE;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

/**
 * 分页标签类
 * 
 * @author Zhang Weiwei
 * @since 2013-10-1上午11:35:08
 */
@SuppressWarnings("serial")
public class PagerTag extends TagSupport {
	private String url;// 访问路径
	private String type = "1";// 分页样式
	private Pager<?> pager;
	private Integer start;
	private Integer end;
	private List<String[]> params;// 查询条件参数集合
	private Integer loopNum = 5;// 页码个数

	@Override
	public int doStartTag() throws JspException {
		HttpServletRequest request = (HttpServletRequest) this.pageContext
				.getRequest();
		this.url = (String) request
				.getAttribute(FORWARD_SERVLET_PATH_ATTRIBUTE);
		this.url = request.getContextPath().concat(this.url);
		this.params = new ArrayList<String[]>();
		return EVAL_BODY_INCLUDE;
	}

	@Override
	public int doEndTag() throws JspException {
		try {
			JspWriter out = this.pageContext.getOut();
			if ("1".equals(this.type)) {
				this.setLoop(this.pager.getNumber(),
						this.pager.getTotalPages(), this.loopNum);
				out.println("<div class=\"pageNumber\">");
				if (this.pager.getNumber() != 1) {
					out.println("<a id=\"first\" onclick=\"paramFormSubmit(1)\" class=\"prev\">首页</a>");
				} else {
					out.println("<span class=\"current prev\">首页</span>");
				}
				if (this.pager.getPrePage() != this.pager.getNumber()) {
					out.println("<a id=\"prev\" onclick=\"paramFormSubmit("
							+ this.pager.getPrePage()
							+ ")\" class=\"prev\">上一页</a>");
				} else {
					out.println("<span class=\"current prev\">上一页</span>");
				}
				if (this.start > 1) {
					out.println("<span class=\"ellipse\">...</span>");
				}
				for (int i = this.start; i <= this.end; i++) {
					if (i == this.pager.getNumber()) {
						out.println("<span class=\"current\">" + i + "</span>");
					} else {
						out.println("<a onclick=\"paramFormSubmit(" + i
								+ ")\">" + i + "</a>");
					}
				}
				if (this.end < this.pager.getTotalPages()) {
					out.println("<span class=\"ellipse\">...</span>");
				}
				if (this.pager.getNextPage() != this.pager.getNumber()) {
					out.println("<a id=\"next\" onclick=\"paramFormSubmit("
							+ this.pager.getNextPage()
							+ ")\" class=\"next\">下一页</a>");
				} else {
					out.println("<span class=\"current next\">下一页</span>");
				}
				if (this.pager.getTotalPages() != this.pager.getNumber()) {
					out.println("<a id=\"last\" onclick=\"paramFormSubmit("
							+ this.pager.getTotalPages()
							+ ")\" class=\"next\" style=\"border-left:0px\">末页</a>");
				} else {
					out.println("<span class=\"current next\" style=\"border-left:0px\">末页</span>");
				}
				out.println("<div style=\"float:left;padding:5px 0 0 5px\">转到</div>");
				out.println("<div style=\"float:left;padding:0 0 0 2px\">");
				out.println("<input type=\"text\" id=\"pageNumText\" value=\""
						+ this.pager.getNumber()
						+ "\" class=\"textinput\" style=\"width:30px;ime-mode:disabled;text-align:center;\" inputMode=\"numberOnly\">");
				out.println("</div>");
				out.println("<div style=\"float:left;padding:5px 0 0 2px\">页</div>");
				out.println("<div style=\"float:left;padding:0 0 0 5px\">");
				out.println("<input type=\"button\" id=\"goToButton\" value=\"确定\" class=\"button\" style=\"min-width:0px\">");
				out.println("</div>");
				out.println("<div style=\"clear:both;\"></div>");
				out.println("</div>");
			} else if ("2".equals(this.type)) {
				this.setLoop(this.pager.getNumber(),
						this.pager.getTotalPages(), this.loopNum);
				out.println("<div class=\"pageArrow\">");
				if (this.pager.getNumber() != 1) {
					out.println("<a id=\"first\" onclick=\"paramFormSubmit(1)\" class=\"pageArrow_first\"></a>");
				} else {
					out.println("<span class=\"current pageArrow_first\"></span>");
				}
				if (this.pager.getPrePage() != this.pager.getNumber()) {
					out.println("<a id=\"prev\" onclick=\"paramFormSubmit("
							+ this.pager.getPrePage()
							+ ")\" class=\"pageArrow_prev\"></a>");
				} else {
					out.println("<span class=\"current pageArrow_prev\"></span>");
				}
				if (this.start > 1) {
					out.println("<span>...</span>");
				}
				for (int i = this.start; i <= this.end; i++) {
					if (i == this.pager.getNumber()) {
						out.println("<span class=\"current\">" + i + "</span>");
					} else {
						out.println("<a onclick=\"paramFormSubmit(" + i
								+ ")\">" + i + "</a>");
					}
				}
				if (this.end < this.pager.getTotalPages()) {
					out.println("<span>...</span>");
				}
				if (this.pager.getNextPage() != this.pager.getNumber()) {
					out.println("<a id=\"next\" onclick=\"paramFormSubmit("
							+ this.pager.getNextPage()
							+ ")\" class=\"pageArrow_next\"></a>");
				} else {
					out.println("<span class=\"current pageArrow_next\"></span>");
				}
				if (this.pager.getTotalPages() != this.pager.getNumber()) {
					out.println("<a id=\"last\" onclick=\"paramFormSubmit("
							+ this.pager.getTotalPages()
							+ ")\" class=\"pageArrow_last\"></a>");
				} else {
					out.println("<span class=\"current pageArrow_last\"></span>");
				}
				out.println("<div style=\"float:left;padding:5px 0 0 4px\">转到</div>");
				out.println("<div style=\"float:left;padding:0 0 0 4px\">");
				out.println("<input type=\"text\" id=\"pageNumText\" value=\""
						+ this.pager.getNumber()
						+ "\" class=\"textinput\" style=\"width:30px;ime-mode:disabled;text-align:center;height:20px\" inputMode=\"numberOnly\">");
				out.println("</div>");
				out.println("<div style=\"float:left;padding:5px 0 0 2px\">页</div>");
				out.println("<div style=\"float:left;padding:0 0 0 5px\">");
				out.println("<input type=\"button\" id=\"goToButton\" value=\"确定\" class=\"button\" style=\"min-width:0px\">");
				out.println("</div>");
				out.println("<div style=\"clear:both;\"></div>");
				out.println("</div>");
			}
			this.paramForm(out);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}

	private void paramForm(JspWriter out) throws IOException {
		if (this.params.isEmpty()) {
			out.println("<script type=\"text/javascript\">");
			out.println("function paramFormSubmit(pageNo) {");
			out.println("location.href=\"" + this.url + "?pageNo=\"+pageNo;");
			out.println("}");
			out.println("</script>");
		} else {
			out.println("<form action=\"" + this.url
					+ "\" method=\"post\" name=\"paramForm\" id=\"paramForm\">");
			for (Object[] param : this.params) {
				out.println(format(
						"<input type=\"hidden\" name=\"%s\" value=\"%s\">",
						param));
			}
			out.println("<input type=\"hidden\" id=\"pageNo\" name=\"pageNo\">");
			out.println("</form>");
			out.println("<script type=\"text/javascript\">");
			out.println("function paramFormSubmit(pageNo) {");
			out.println("$(\"#pageNo\").val(pageNo);");
			out.println("$(\"#paramForm\").submit();");
			out.println("}");
			out.println("$(function() {");
			out.println("$(\"#goToButton\").click(function() {");
			out.println("var pageNumText=$(\"#pageNumText\").val();");
			out.println("paramFormSubmit(pageNumText);");
			out.println("});");
			out.println("$(\"#pageNumText\").blur(function(){");
			out.println("if(this.value>" + this.pager.getTotalPages() + "){");
			out.println("this.value=" + this.pager.getTotalPages() + ";");
			out.println("}");
			out.println("});");
			out.println("});");
			out.println("</script>");
		}
	}

	private void setLoop(int page, int total, int x) {
		if (total > x) {
			if (page > (x / 2) + 1) {
				if (page > total - (x / 2) - 1) {
					this.start = total - x + 1;
					this.end = total;
				} else {
					this.start = page - (x / 2);
					if ((x % 2) == 0) {
						this.end = page + (x / 2) - 1;
					} else {
						this.end = page + (x / 2);
					}
				}
			} else {
				this.start = 1;
				this.end = x;
			}
		} else {
			this.start = 1;
			this.end = total;
		}
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setType(String type) {
		this.type = type;
	}

	public void setPager(Pager<?> pager) {
		this.pager = pager;
	}

	public void setParams(List<String[]> params) {
		this.params = params;
	}

	public void addParams(String[] params) {
		this.params.add(params);
	}

	public void setLoopNum(Integer loopNum) {
		this.loopNum = loopNum;
	}
}
